package com.qd.pay.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdqidi.constant.ConstantDto;
import com.cdqidi.dto.ApiResult;
import com.cdqidi.dto.CacheKey;
import com.cdqidi.exception.ApiException;
import com.cdqidi.util.RedisTemplateUtil;
import com.qd.pay.domain.WxBillsTimeDTO;
import com.qd.pay.model.WxBillsTime;
import com.qd.pay.repository.WxBillsTimeRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author sjk
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class WxBillsTimeService {

    private final WxBillsTimeRepository wxBillsTimeRepository;
    @Resource
    private RedisTemplateUtil<WxBillsTime> redisTemplateUtil;

    private static final String PREFIX_ID = "wx_bills_time_tjsj_{0}";

    @Transactional(rollbackFor = Exception.class)
    public WxBillsTime save(WxBillsTime model) throws ApiException {
        try {
            if (!wxBillsTimeRepository.save(model)) {
                throw new ApiException(ApiResult.error());
            }
            return model;
        } finally {
            clearCache(model);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(WxBillsTime model) throws ApiException {
        final WxBillsTime historyModel = Optional.ofNullable(getById(model.getBid())).orElseThrow(() -> new ApiException("ID不存在,不能更新"));
        try {
            if (!wxBillsTimeRepository.updateById(model)) {
                throw new ApiException(ApiResult.error());
            }
            return true;
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean removeById(String bid) throws ApiException {
        final WxBillsTime historyModel = Optional.ofNullable(getById(bid)).orElseThrow(() -> new ApiException("ID不存在,不能删除"));
        try {
            if (!wxBillsTimeRepository.removeById(bid)) {
                throw new ApiException(ApiResult.error());
            }
            return true;
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
        }
    }

    public Boolean isExists(Integer bid) {
        return wxBillsTimeRepository.isExists(bid);
    }

    public WxBillsTime getById(String bid) {
        String key = RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, bid);
        return redisTemplateUtil.get(new CacheKey().setKey(key).setTimeout(ConstantDto.REDIS_TIME_OUT_DAY * 3), () -> wxBillsTimeRepository.getById(bid), WxBillsTime.class);
    }

    public IPage<WxBillsTimeDTO> page(Page<WxBillsTimeDTO> page, WxBillsTime model) {
        QueryWrapper<WxBillsTime> queryWrapper = new QueryWrapper<>(model);
        IPage<WxBillsTime> iPage = wxBillsTimeRepository.page(page.convert(this::dtoToModel), queryWrapper);
        return iPage.convert(this::modelToDto);
    }


    private void clearCache(WxBillsTime model) {
        if (null == model) {
            return;
        }
        String key = RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, model.getBid());
        redisTemplateUtil.deleteByKey(key);
    }

    public WxBillsTimeDTO modelToDto(WxBillsTime model) {
        if (null == model) {
            return null;
        }
        WxBillsTimeDTO dto = new WxBillsTimeDTO();
        dto.setTjsj(model.getTjsj());
        dto.setSingular(model.getSingular());
        dto.setTotalFee(model.getTotalFee());
        dto.setRefund(model.getRefund());
        dto.setEnterprisebonusamount(model.getEnterprisebonusamount());
        dto.setServicecharge(model.getServicecharge());
        dto.setWxorgid(model.getWxorgid());
        dto.setBid(model.getBid());
        model.freeData();
        return dto;
    }

    public WxBillsTime dtoToModel(WxBillsTimeDTO dto) {
        if (null == dto) {
            return null;
        }
        WxBillsTime model = new WxBillsTime();
        model.setTjsj(dto.getTjsj());
        model.setSingular(dto.getSingular());
        model.setTotalFee(dto.getTotalFee());
        model.setRefund(dto.getRefund());
        model.setEnterprisebonusamount(dto.getEnterprisebonusamount());
        model.setServicecharge(dto.getServicecharge());
        model.setWxorgid(dto.getWxorgid());
        model.setBid(dto.getBid());
        dto.freeData();
        return model;
    }

}